package com.rockcent.third.helper;

import com.rockcent.common.domain.enumclass.Whether;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.dto.MallMerchantDto;
import com.rockcent.mall.lib.dto.UserInfoDto;
import com.rockcent.mall.lib.helper.BaseUserHelper;
import com.rockcent.mall.lib.repository.MallRepository;
import com.rockcent.mall.lib.repository.MerchantRepository;
import com.rockcent.mall.lib.repository.UserMallRepository;
import com.rockcent.third.utils.CommonUtils;
import com.rockcent.third.utils.FreemarkerUtil;
import com.rockcent.third.Prop;
import com.rockcent.mall.lib.domain.enumclass.EmailTemplateCode;
import com.rockcent.mall.lib.repository.EmailTemplateRepository;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * Created by oyhk on 16/2/6.
 * user 实体类的帮助工具
 */
@Component
public class UserHelper extends BaseUserHelper {

    private static Logger log = LoggerFactory.getLogger(UserHelper.class);
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private Prop prop;
    @Autowired
    private EmailTemplateRepository emailTemplateRepository;
    @Autowired
    private ExecutorService commonExecutorService;
    @Autowired
    private MallRepository mallRepository;
    @Autowired
    private MerchantRepository merchantRepository;
    @Autowired
    private UserMallRepository userMallRepository;

    /**
     * 通过明文的密码，获取md5后的密码
     * @param lawsPassword
     * @return
     */
    public String getMd5Password(String passwordTimeStamp, String lawsPassword) {
        return DigestUtils.md5Hex(UserInfo.SSO_PASSWORD_ENCODE_KEY + passwordTimeStamp + lawsPassword);
    }

    public void sendEmail(String redisKeyPrefix, String username, EmailTemplateCode code, String activeUrlPrefix) throws Exception {
        EmailTemplate template = emailTemplateRepository.findByCode(code);
        String redisKey = redisKeyPrefix + username + "___" + CommonUtils.getRandom6();
        String redisValue = CommonUtils.getRandom6();
        redisTemplate.boundValueOps(redisKey).set(redisValue);
        redisTemplate.expire(redisKey, 1, TimeUnit.DAYS);// 设置1天有效期

        // key 生成 ,这里暂时使用简单的base64 加密 , key 的格式  381895649@qq.com_123513||234233
        String key = Base64.encodeBase64String(String.format("%s||%s", redisKey.replace(redisKeyPrefix, ""), redisValue).getBytes());
        String activeUrl = activeUrlPrefix+"/"+key+"/"+username;
        MimeMessage mail = mailSender.createMimeMessage();
        MimeMessageHelper helper = new MimeMessageHelper(mail, true);

        Map<String, Object> root = new HashMap<>();
        root.put("C_SYSTEM_NAME", "络享");
        root.put("B_SERVICE_MAIL", "marketing@rockcent.com");
        root.put("DOMAIN_WEBSITE", "www.rockcent.com");
        root.put("account", username);
        root.put("activeUrl", "http://"+activeUrl);
        root.put("nowDate", DateFormatUtils.format(new Date(), DateFormatUtils.ISO_DATE_FORMAT.getPattern()));
        helper.setTo(username);
        helper.setReplyTo(username);
        helper.setFrom(prop.springMailUsername);
        helper.setSubject(FreemarkerUtil.parseString(template.getTitle(), root));
        helper.setText(FreemarkerUtil.parseString(template.getContent(), root), true);
        //采用异步线程池 发送邮件
        commonExecutorService.execute(() -> {
            log.info("======================>send email start");
            mailSender.send(mail);
            log.info("======================>send email end");
        });
    }

    /**
     * 验证邮件的url是否有效
     * @param key key
     * @return username
     */
    public String verifyEmail(String key, String redisKeyPrefix, boolean isDeleteKey) {
        String usernameAndRandom = getUsernameByEmailKey(key, redisKeyPrefix);
        if (StringUtils.isBlank(usernameAndRandom)) {
            return null;
        }
        if (isDeleteKey) {
            redisTemplate.delete(redisKeyPrefix + usernameAndRandom);// 激活成功删除key
        }

        // usernameAndRandom = 381895649@qq.com_123456
        String username = usernameAndRandom.split("___")[0];
        return username;
    }

    /**
     * 邮件的链接的key 解析 username
     * @param key
     * @param redisKeyPrefix
     * @return
     */
    private String getUsernameByEmailKey(String key, String redisKeyPrefix) {
        String[] keyAndValue = new String(Base64.decodeBase64(key.getBytes())).split("\\|\\|");
        if (keyAndValue.length != 2) {
            return null;
        }
        //  获取redis的可以 key value
        String value = redisTemplate.opsForValue().get(redisKeyPrefix + keyAndValue[0]);

        if (StringUtils.isBlank(value) || !value.equals(keyAndValue[1])) {
            return null;
        }
        return keyAndValue[0];
    }

    /**
     * 在 session 获取权限列表
     * @param userInfoDto
     * @return
     */
    public List<Map<String, Object>> getPermissionList(UserInfoDto userInfoDto) {
        List<Map<String, Object>> permissionList = new ArrayList<>();
        if(userInfoDto==null) {
            return permissionList;
        }
        Long userId = userInfoDto.getId();
        if(userId==null) {
            return permissionList;
        }
        log.info("======================>getPermissionList permissionMap:{}",userInfoDto.getPermissionMap());
        Map<String, List<MallMerchantDto>> map = userInfoDto.getPermissionMap();
        if(map!=null && map.size()>0) {
            for(Map.Entry<String, List<MallMerchantDto>> entry:map.entrySet()){
                List<MallMerchantDto> list = entry.getValue();
                if(list!=null && list.size()>0) {
                    Map permission = new LinkedHashMap<>();
                    permission.put("mallName", list.get(0).getMallName());
                    permission.put("mallBigLogoPath", list.get(0).getMallBigLogoPath());
                    permission.put("mallLogoPath", list.get(0).getMallLogoPath());
                    List<Map<String, String>> merchantList = new ArrayList<>();
                    for (MallMerchantDto mallMerchantDto:list) {
                        if(StringUtils.isNotEmpty(mallMerchantDto.getMallUrl())) {
                            permission.put("mallUrl", mallMerchantDto.getMallUrl());
                        }
                        if(StringUtils.isNotEmpty(mallMerchantDto.getMerchantUrl())) {
                            Map merchantPermission = new LinkedHashMap<>();
                            merchantPermission.put("merchantId",mallMerchantDto.getMerchantId());
                            merchantPermission.put("merchantName",mallMerchantDto.getMerchantName());
                            merchantPermission.put("merchantUrl",mallMerchantDto.getMerchantUrl());
                            merchantList.add(merchantPermission);
                        }
                    }
                    permission.put("merchants",merchantList);
                    permissionList.add(permission);
                }
            }
        }
        return permissionList;
    }

    /**
     * 判断是否是自定义登录
     * 如果是就设置相关信息
     * @param userInfo
     * @param request
     * @return
     */
    public UserInfoDto checkCustomLogin(UserInfo userInfo, HttpServletRequest request) {
        if(userInfo==null) {
            return null;
        }
        String refererUrl = request.getHeader("referer");
        UserInfoDto user = new UserInfoDto();
        user.setId(userInfo.getId());
        user.setUsername(userInfo.getUsername());
        if(StringUtils.isNotEmpty(refererUrl)) {
            refererUrl = refererUrl.replace("http://", "");
            if (refererUrl.contains("/")) {
                refererUrl = refererUrl.split("/")[0];
            }
            if (refererUrl.contains(":")) {
                refererUrl = refererUrl.split(":")[0];
            }
            //判断来源是否是自定义地址
            if (!prop.domainWww.contains(refererUrl)) {
                user.setReferer(refererUrl);
                //根据域名查询对应的平台
                Mall mall = mallRepository.findByCustomerPlatformDomain(refererUrl);
                if(mall!=null) {
                    if(checkUserInfoMall(user, mall)) {
                        return user;
                    }
                }
            }
        }
        return user;
    }

    /**
     * 检查用户是否属于该本台
     * @param userInfoDto
     * @param mall
     */
    public boolean checkUserInfoMall(UserInfoDto userInfoDto, Mall mall) {
        if(userInfoDto==null || mall==null) {
            return false;
        }
        boolean isPass = false;
        //用户属于该本台
        if(StringUtils.isNotEmpty(mall.getCustomerPlatformDomain()) && mall.getOpenCustomDomain()!=null && Whether.YES.equals(mall.getOpenCustomDomain())) {
            if(userInfoDto.getId()!=null && mall.getUserInfoId()!=null && userInfoDto.getId().longValue()==mall.getUserInfoId().longValue()) {
                userInfoDto.setCustomLoginMallUrl(String.format("http://%s/mall_new/mobile_banner", mall.getCustomerPlatformDomain()));
                userInfoDto.setCustomLogin("Y");
                isPass = true;
            }
            //获取用户商家
            Merchant merchant = getMerchantByMallAndUserId(mall.getId(),userInfoDto.getId());
            if(merchant!=null) {
                userInfoDto.setCustomLoginMerchantUrl(String.format("http://%s/business/merchant/index", mall.getCustomerPlatformDomain()));
                userInfoDto.setCustomLogin("Y");
                isPass = true;
            }
        }
        return isPass;
    }

    /**
     * 获取用户商家
     * @param mallId
     * @param userId
     * @return
     */
    public Merchant getMerchantByMallAndUserId(Long mallId, Long userId) {
        return merchantRepository.findByUserInfoIdAndMallId(userId,mallId);
    }

    /**
     * 检查域名有效性
     * @param hostname
     * @return
     */
    public boolean checkHostname(String hostname) {
        if(StringUtils.isEmpty(hostname)) {
            return false;
        }
        String siteWWW = prop.domainWww.replace("http://", "");
        if(siteWWW.equals(hostname)) {
            return true;
        }
        hostname = hostname.replace("http://", "");
        Mall mall = mallRepository.findByHostnameOrCustomerPlatformDomain(hostname);
        if(mall!=null) {
            return true;
        }
        return false;
    }

}
